/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package jlibrarian.desktop;

import java.lang.reflect.Method;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;
import javax.swing.table.DefaultTableModel;

/**
 *
 * @author xmach9
 */
public class JLibrarianTableModel extends DefaultTableModel {
    private String[] columnNames = {};
    private String[] columns = {};

//    private Object[][] data;
    private List<List<Object>> data = new ArrayList<List<Object>>();

    public synchronized void clear(){
        this.data.clear();
        fireTableDataChanged();    
    }

    public synchronized void setColumnNames(String[] columnNames)
    {
        this.columnNames = columnNames;
        for(String name : this.columnNames){
            this.addColumn(name);
        }
    }

    public synchronized void setColumns(String[] columns)
    {
        this.columns = columns;
        
    }



    // sets data
    public synchronized void setDataFromCollection(Collection c)
    {
        this.data.clear();
        
        for(Object jlibrarianObject : c)
        {
            List<Object> row = new ArrayList<Object>();
            for(String column : this.columns)
            {
                String methodName = "get" + column.substring(0,1).toUpperCase() + column.substring(1);
                Method m;
                Object value = new Object();

                // tries the method
                try{
                    Method method = jlibrarianObject.getClass().getDeclaredMethod(methodName);
                    value = method.invoke(jlibrarianObject);
                   
                }catch(Exception e)
                {
                    throw new RuntimeException("Called method " + methodName  +" not found.", e);
                }
                
                row.add(value);
            }

            this.data.add(row);
        }
        fireTableDataChanged();
    }



    @Override
    public synchronized int getColumnCount() {
        return this.columnNames.length;
    }

    @Override
    public synchronized int getRowCount() {
        if(this.data == null) return 0;
        return this.data.size();
    }

    @Override
    public synchronized String getColumnName(int col) {
        return columnNames[col];
    }

    @Override
    public synchronized Object getValueAt(int row, int col) {
        Object d = data.get(row).get(col);
        if(d instanceof Calendar)
        {
            Calendar dc = (Calendar) d;
            d = DateFormat.getDateInstance().format(dc.getTime());
        }
        return d;
    }

    public synchronized Object getValueByType(int row, Class type) {
        for(Object obj : data.get(row)){
            if(type.isInstance(obj))
            {
                return obj;
            }
        }
        return null;
    }

  /*  @Override
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }
*/
    /*
     * Don't need to implement this method unless your table's
     * editable.
     */
    @Override
    public boolean isCellEditable(int row, int col) {
        //Note that the data/cell address is constant,
        //no matter where the cell appears onscreen.
        return false;
      
    }

    /*
     * Don't need to implement this method unless your table's
     * data can change.
     */
    @Override
        public synchronized void setValueAt(Object value, int row, int col) {
        data.get(row).set(col, value);
        fireTableCellUpdated(row, col);
    }
}
